package controllers

import (
	"github.com/kataras/iris"
	"log"
	"lottery/comm"
	"lottery/datasource"
	"lottery/models"
	"lottery/services"
	"lottery/web/utils"
)

// 控制器
type EventsController struct {
	Ctx           iris.Context
	ServiceAward  services.AwardService
	ServiceEvent  services.EventService
	ServiceResult services.ResultService
	ServiceUser   services.UserService
}

// 新建活动
type eventReq struct {
	Token     string `json:"token"`
	EventName string `json:"event_name"`
	Desc      string `json:"desc"`
	TypeNum   int    `json:"type"`
	Img       string `json:"img"`
	Data      []item `json:"data"`
	StartAt   int    `json:"start_at"`
	StopAt    int    `json:"stop_at"`
}

// 新建活动中的奖品
type item struct {
	Name      string `json:"name"`
	MaxAmount int    `json:"max_amount"`
	Img       string
	Desc      string
	Weight    int
	Percent   int
}

// POST /events/new params: json
// 新建一个新的抽奖活动
func (c *EventsController) PostNew() map[string]interface{} {

	// 解析Json
	reqToken := &eventReq{}
	jsonErr := c.Ctx.ReadJSON(reqToken)
	if jsonErr != nil {
		log.Println("events.PostNew() failed err=", jsonErr)
		return utils.RespCode(500)
	}

	// Token 登录验证
	ret, claims, err := utils.VerifyESToken(reqToken.Token)
	if err != nil {
		// 解析 Token 失败
		log.Println("events.PostNew() failed err=", err)
		return utils.RespCode(500)
	} else if !ret {
		// 签名验证失败
		return utils.RespCode(100)
	}

	// 验证数据是否有效
	sum := 0
	for _, item := range reqToken.Data {
		sum += item.Percent
	}
	if sum != 100 {
		// 如果百分比加起来非 100 则返回错误
		return map[string]interface{}{
			"code": 220,
			"msg":  "percent param error",
		}
	}

	// 通过 Token 获取登录的用户 Id
	userId := comm.GetInt64(claims.Get("user_id"), -1)

	// 新建一个会话
	session := datasource.InstanceDbMaster().NewSession()

	// 开启一个事务
	if err := session.Begin(); err != nil {
		log.Println("events.PostNew() session begin failed, err=", err)
		return utils.RespCode(500)
	}

	// 将新的抽奖活动插入到数据库当中
	event := &models.TbEvent{
		Name:       reqToken.EventName,
		Desc:       reqToken.Desc,
		Img:        reqToken.Img,
		Status:     1,
		Type:       reqToken.TypeNum,
		UserId:     int(userId),
		StartAt:    reqToken.StartAt,
		StopAt:     reqToken.StopAt,
		CreateTime: comm.NowUnix(),
		UpdateTime: comm.NowUnix(),
	}

	if _, err := session.Insert(event); err != nil {
		// 数据库插入失败
		log.Println("events.PostNew() failed err=", err)
		_ = session.Rollback()
		return utils.RespCode(500)
	}

	// 获取抽奖活动中的奖品，并将其插入到数据库当中去
	items := reqToken.Data
	areaNum := 0 // 获奖区间临时变量
	for _, item := range items {

		_, sessionErr := session.Insert(&models.TbAward{
			Desc:       item.Desc,
			Img:        item.Img,
			Name:       item.Name,
			Weight:     item.Weight,
			AreaFrom:   areaNum,
			AreaTo:     areaNum + (10 * item.Percent),
			MaxAmount:  item.MaxAmount,
			RestAmount: item.MaxAmount,
			EventId:    event.Id,
			CreateTime: comm.NowUnix(),
			UpdateTime: comm.NowUnix(),
		})
		if sessionErr != nil {
			// 数据库插入失败
			_ = session.Rollback()
			return utils.RespCode(500)
		}
		areaNum = areaNum + (10 * item.Percent)
	}

	// 提交事务
	if err := session.Commit(); err != nil {
		_ = session.Rollback()
		log.Println("events.PostNew() session commit failed , err=", err)
		return utils.RespCode(500)
	}
	return utils.RespCode(0)
}

// POST /events/my params: token
// 显示我的活动列表
func (c *EventsController) PostMy() map[string]interface{} {

	token := c.Ctx.FormValue("token")
	ret, claims, err := utils.VerifyESToken(token)
	if err != nil {
		// token 解析失败
		return utils.RespCode(500)
	} else if !ret {
		// token 验证失败
		return utils.RespCode(500)
	}
	userId := comm.GetInt64(claims.Get("user_id"), -1)

	events := c.ServiceEvent.GetByUser(int(userId))

	eventsData := make([]models.Events, 0)
	for _, event := range events {

		awards := c.ServiceAward.GetByEvent(event.Id)

		awardsData := make([]models.Awards, 0)
		for _, award := range awards {
			awardModel := models.Awards{
				Id:         award.Id,
				Name:       award.Name,
				Desc:       award.Desc,
				RestAmount: award.RestAmount,
				MaxAmount:  award.MaxAmount,
				Img:        award.Img,
				Percent:    (award.AreaTo - award.AreaFrom) / 10,
			}
			awardsData = append(awardsData, awardModel)
		}
		eventModel := models.Events{
			Id:      event.Id,
			Name:    event.Name,
			Desc:    event.Desc,
			Type:    event.Type,
			Img:     event.Img,
			Status:  event.Status,
			Awards:  awardsData,
			StartAt: event.StartAt,
			StopAt:  event.StopAt,
		}
		eventsData = append(eventsData, eventModel)
	}

	return map[string]interface{}{
		"code": 0,
		"msg":  "success",
		"data": eventsData,
	}
}

// POST /events/delete params: event_id
// 软删除一项活动
func (c *EventsController) PostDelete() map[string]interface{} {

	eventId := int(comm.GetInt64(c.Ctx.FormValue("event_id"), -1))
	// 登录验证
	token := c.Ctx.FormValue("token")
	ret, claims, err := utils.VerifyESToken(token)
	if err != nil {
		// token 解析失败
		return utils.RespCode(500)
	} else if !ret {
		// token 验证失败
		return utils.RespCode(500)
	}
	userId := comm.GetInt64(claims.Get("user_id"), -1)

	has, data := c.ServiceUser.Get(int(userId))
	if !has {
		// 用户不存在
		return utils.RespCode(140)
	}

	has, event := c.ServiceEvent.Get(eventId)
	if !has {
		return map[string]interface{}{
			"code": "240",
			"msg":  "event is not exist",
		}
	}
	if event.UserId != data.Id {
		return map[string]interface{}{
			"code": "250",
			"msg":  "event is not yours",
		}
	}

	err = c.ServiceEvent.Update(&models.TbEvent{
		Id:         eventId,
		Status:     -1,
		UpdateTime: comm.NowUnix(),
	}, []string{"status"})

	if err != nil {
		// 修改失败
		return utils.RespCode(500)
	}

	return utils.RespCode(0)

}
